package Comp355Final.main;

import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.nio.ByteBuffer;
import java.nio.charset.CharacterCodingException;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import java.util.ArrayList;
import java.util.List;

import android.content.Context;
import android.os.Environment;

public class FileIO {
	private String sdcard_now_position;
	private String sdcard_root;
	private String[] supported_ext = {"txt","png","jpg","gif"};
	private String[] supported_Imgext = {"png","jpg","gif"};
	
	private String bookfolder;
	public FileIO(String bookfolder) {
		File sdcard = Environment.getExternalStorageDirectory();
		sdcard_root = sdcard.getAbsolutePath()  + "/bookshelf/";
		sdcard_now_position = sdcard.getAbsolutePath()  + "/bookshelf/"+bookfolder+"/";
		this.bookfolder=bookfolder;
	}
	private boolean file_selector;
	public FileIO(boolean file_selector,String bookfolder) {
		this.file_selector=true;
		File sdcard = Environment.getExternalStorageDirectory();
		sdcard_root = sdcard.getAbsolutePath();
		sdcard_now_position = sdcard.getAbsolutePath()+bookfolder;
		this.bookfolder=bookfolder;
	}
	public FileIO() {
		File sdcard = Environment.getExternalStorageDirectory();
		sdcard_root = sdcard.getAbsolutePath()  + "/bookshelf/";
		sdcard_now_position = sdcard.getAbsolutePath()  + "/bookshelf/";

		File tmp_folder = new File(sdcard_now_position);
		if(!tmp_folder.exists())
		{
			tmp_folder.mkdirs();
		}
		tmp_folder = new File(sdcard_now_position+"covers/");
		if(!tmp_folder.exists())
		{
			tmp_folder.mkdirs();
		}
		tmp_folder = new File(sdcard_now_position+"configs/");
		if(!tmp_folder.exists())
		{
			tmp_folder.mkdirs();
		}
		tmp_folder = new File(sdcard_now_position+"backgrounds/");
		if(!tmp_folder.exists())
		{
			tmp_folder.mkdirs();
		}
	}
	public static String getFileExt(String dest)
	{
		File tmp_file = new File(dest);
		
		String[] returnExtSplit = tmp_file.getName().toLowerCase().split("\\.");
		return returnExtSplit[returnExtSplit.length-1];
	}
	public String getParentDirectory()
	{
		File tmp_file = new File(this.sdcard_now_position);
		return tmp_file.getParentFile().getAbsolutePath();
	}
	public static String getRootDirectory()
	{
		return Environment.getExternalStorageDirectory().getAbsolutePath();
	}
	public void set_fileCursor(String sdcard_now_position)
	{
		this.sdcard_now_position=sdcard_now_position;
	}
	public String get_sdcard_root()
	{
		return this.sdcard_root;
	}
	public boolean make_file(String dest)
	{
		File tmp_file = new File(dest);
		boolean create_result=false;
		try
		{
			create_result=tmp_file.createNewFile();
			
		}
		catch (Exception e)
		{
			return false;
		}

		return create_result;
	}
	public boolean make_folder(String dest)
	{
		File tmp_folder = new File(dest);
		try
		{
			tmp_folder.mkdirs();
			
		}
		catch (Exception e)
		{
			return false;
		}

		return true;
	}
	public String get_sdcard_dest()
	{
		return this.sdcard_now_position;
	}
	public boolean check_Folderexisted(String dest)
	{
		File myfile = new File(dest);
		if(myfile.exists()&&myfile.isDirectory())
		{
			return true;
		}
		else
		return false;

		
	}
	public boolean check_Fileexisted(String dest)
	{
		File myfile = new File(dest);
		if(myfile.exists()&&myfile.isFile())
		{
			return true;
		}
		else
		return false;

		
	}
	public static boolean delete_file(String dest)
	{
		boolean deleted = false;
		File file = new File(dest);
		try
		{
		deleted = file.delete();
		}
		catch(Exception e)
		{}
		return deleted;
	}
	
	public ArrayList<String> filter_ImgExt(ArrayList<String> folder_list)
	{
		ArrayList<String> return_list = new ArrayList<String>();
		for(int i=0;i<folder_list.size();i++)
		{
			for(int y=0;y<supported_Imgext.length;y++)
			{
				if(folder_list.get(i).toLowerCase().endsWith(supported_Imgext[y]))
					return_list.add(folder_list.get(i));
			}
		}
			return return_list;
	}
	public ArrayList<String> is_folder (ArrayList<String> path_list)
	{
		ArrayList<String> new_list = new ArrayList<String>();
		for(int i=0;i<path_list.size();i++)
		{
			File tmp_file = new File(path_list.get(i));
			if(tmp_file.isDirectory())
				new_list.add(path_list.get(i));
		}
		return new_list;
	}
	public ArrayList<String> filter_folder(ArrayList<String> folder_list)
	{
		ArrayList<String> result_array = new ArrayList<String>();
		
		for(int i=0;i<folder_list.size();i++)
		{
			boolean AddThis = true;

			File tmp_file = new File(folder_list.get(i));
			try
			{
				if(!tmp_file.isDirectory())
					AddThis=false;
			}
			catch(Exception e)
			{
				AddThis=false;
			}
			if(AddThis&&!folder_list.get(i).endsWith("/covers")&&!folder_list.get(i).endsWith("/backgrounds")&&!folder_list.get(i).endsWith("/configs"))
				result_array.add(folder_list.get(i));
		}

			return result_array;
	}
	public ArrayList<String> filter_allExt(ArrayList<String> folder_list)
	{
		ArrayList<String> return_list = new ArrayList<String>();
		for(int i=0;i<folder_list.size();i++)
		{
			for(int y=0;y<supported_ext.length;y++)
			{
				//System.out.println("testing"+folder_list.get(i).toLowerCase().endsWith(supported_ext[y]));
				if(folder_list.get(i).toLowerCase().endsWith(supported_ext[y]))
					return_list.add(folder_list.get(i));
			}
		}
			return return_list;
	}
	public ArrayList<String> scan_folder()
	{
		ArrayList<String> paths = new ArrayList<String>();

		File directory = new File(this.sdcard_now_position);
		File[] files;
		
		files = directory.listFiles();
		if (files==null)
		{
			return null;
		}
		for (int i = 0; i < files.length; i++)
		{
			paths.add(files[i].getAbsolutePath());
		}
		

		return paths;
	}
	
	public ArrayList<String> scan_img_folder()
	{
		ArrayList<String> paths = new ArrayList<String>();
		File directory = new File(this.sdcard_root+"covers/");
		File[] files = directory.listFiles();
		for (int i = 0; i < files.length; ++i)
		{
			paths.add(files[i].getAbsolutePath());
		}
		return paths;
	}
	public boolean writefileOP(ArrayList<String> content,String file_des, String codec){
		File myfile = new File(file_des);
		if(!myfile.exists())
		{
			try {
				//System.out.println(file_des+"File is creating.");
				myfile.createNewFile();
				//System.out.println("File is created.");
			} catch (IOException e) {
			}
		}
		Charset char_set = Charset.forName(codec);
		int BUFFER_SIZE = 8192;
		try {
			BufferedWriter br = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file_des), char_set),BUFFER_SIZE);
			for(int i=0;i<content.size();i++)
			{
			br.write(content.get(i)+"\r\n");
			br.flush();
			}
			br.close();
		} catch (Exception e) {
			return false;
		}
		return true;
	}

	public ArrayList<String> ReadfileOP(String file_des,String codec)
	{
		ArrayList<String> result_string=new ArrayList<String>();
		try {
        	String filePath = file_des;

        	Charset mycodec = Charset.forName(codec);
        	int BUFFER_SIZE = 8192;
        	BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(filePath), mycodec),BUFFER_SIZE);

        	String line;
        	while ((line = br.readLine()) != null)
        	{
        		result_string.add(line);
        	}
        	br.close();
        	
		}
		catch (Exception e) {
			
		}
		return result_string;
	}
	public String textViewReadfileOP(String file_des,String codec){
        
		
		StringBuilder text = new StringBuilder();
  
    	ArrayList<String> tmp_string = ReadfileOP(file_des,codec);
    	for(int i=0;i<tmp_string.size();i++)
    	{
    		text.append(tmp_string.get(i));
    		text.append('\n');
    	}
    	//text.append(sdcard);
    	return text.toString();
	}
	public static boolean delete_hole_folder(String tmp_delDest, Context context, GUIBookShelfBkSelect guibsbs){
		boolean return_result = true;
		FileIO myfileio = new FileIO();
		File tmp_file = new File(tmp_delDest);
		//Utility.quick_dialog(this.path_list.get(panel_id_selected), this);
		myfileio.set_fileCursor(tmp_delDest);
		ArrayList<String> path_list = myfileio.scan_folder();
		if(path_list.size()>0)
		{
			Utility.getAlertDialog("Folder not empty", "Are you sure that you want to delete all files?", context, new DiologClickListener(context, path_list, tmp_file,guibsbs)).show();
			return_result=false;
		}
		else
		{
			try
			{
				return_result=tmp_file.delete();
			}
			catch(Exception e)
			{
				return_result=false;
			}
		}
		return return_result;
	}
	public boolean reNameFolderOrFile(String org_dest,String tar_folder)
	{
		if(this.check_Fileexisted(this.sdcard_root+tar_folder))
			return false;
		if(this.check_Folderexisted(this.sdcard_root+tar_folder))
			return false;
		File tmp_orgfileio = new File(org_dest);
		File tmp_tarfileio = new File(this.sdcard_root+tar_folder);
		try
		{
			tmp_orgfileio.renameTo(tmp_tarfileio);
		}
		catch(Exception e)
		{
			return false;
		}
		return true;
		
	}
	public static boolean copy(File src, File dst){
		boolean return_result=false;
		try
		{
		    InputStream in = new FileInputStream(src);
		    OutputStream out = new FileOutputStream(dst);
	
		    // Transfer bytes from in to out
		    byte[] buf = new byte[1024];
		    int len;
		    while ((len = in.read(buf)) > 0) {
		        out.write(buf, 0, len);
		    }
		    return_result=true;
		    in.close();
		    out.close();
		}
		catch(Exception e){}
		return return_result;
	}
	public static long fileSize(String in_path)
	{
		File myfile = new File(in_path);
		long size=0;
		try
		{
		size = myfile.length();
		}
		catch(Exception e)
		{
		
		}
		return size;
		
	}
}
